#include"snake.h"
#include"user.c"

int main(){

    CONSOLE_CURSOR_INFO cci;
    cci.dwSize=1;
    cci.bVisible=FALSE;

    //SetConsoleCursorPosition(hOut,coord);
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);

    system("mode con cols=60 lines=25");

    srand(time(NULL)); //播种随机数种子

    initUserSystem();
    initUser();

    playGame();
    gameOver();

    while (head != NULL) {
        UserNode* temp = head;
        head = head->next;
        free(temp);
    }
    
    return 0;
}

void initGame(){
    game.currentDir=DIR_RIGHT;
    game.lastDir=DIR_RIGHT;
    game.gameOver=false;
    game.score=0;
    game.speed=200;
    game.level=1;
    obstacleCount = 0; // 初始化障碍物数量
    isPaused=false;
}

void showPauseScreen(){    
    COORD coord;
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    system("cls");
    initWall();
    
    coord.X=WIDE/2;
    coord.Y = HIGH/2;
    SetConsoleCursorPosition(hOut, coord);
    printf("Game is Paused");
    
    coord.X=WIDE/2 ;
    coord.Y = HIGH/2 + 1;
    SetConsoleCursorPosition(hOut, coord);
    printf("Press Space to Continue");

    coord.X=WIDE/2;
    coord.Y=HIGH/2+2;
    SetConsoleCursorPosition(hOut, coord);
    printf("Press Q to Quit");

    showLevalInfo();
}

void resumeGameScreen(){
    initUI();
    showLevalInfo();
}

void initSnake(){
    snake.size=3;   //蛇的长度
    for(size_t i=0; i<snake.size; i++){
        snake.body[i].X=WIDE/2-i;
        snake.body[i].Y=HIGH/2;
    }
}

void initFood(){
    bool isOnSnake;
    
    do{
        isOnSnake=FALSE;

        food.X=rand()%(WIDE-2)+1;
        food.Y=rand()%(HIGH-2)+1;

        // 检查食物是否与蛇身重叠
        for(size_t i=0; i<snake.size; i++){
            if(food.X==snake.body[i].X&&food.Y==snake.body[i].Y){
                isOnSnake=TRUE;
                break;
            }
        }
        
        //检查食物是否与障碍物重叠
        for(int i=0; i<obstacleCount; i++){
            if(food.X==obstacles[i].X&&food.Y==obstacles[i].Y){
                isOnSnake=TRUE;
                break;
            }
        }
        
    }while(isOnSnake);
}

// 初始化障碍物
void initObstacles() {
    obstacleCount = 0;
    
    // 根据关卡决定障碍物数量
    int count = game.level * 2;
    if(count > MAX_OBSTACLES) count = MAX_OBSTACLES;
    
    for(int i=0; i<count; i++) {
        bool validPosition;
        do {
            validPosition = true;
            obstacles[i].X = rand()%(WIDE-2)+1;
            obstacles[i].Y = rand()%(HIGH-2)+1;
            
            // 确保障碍物不会出现在蛇身上
            for(size_t j=0; j<snake.size; j++) {
                if(obstacles[i].X == snake.body[j].X && obstacles[i].Y == snake.body[j].Y) {
                    validPosition = false;
                    break;
                }
            }
            
            // 确保障碍物不会出现在食物位置
            if(obstacles[i].X == food.X && obstacles[i].Y == food.Y) {
                validPosition = false;
            }
            
            // 确保障碍物之间不会重叠
            for(int j=0; j<i; j++) {
                if(obstacles[i].X == obstacles[j].X && obstacles[i].Y == obstacles[j].Y) {
                    validPosition = false;
                    break;
                }
            }
            
        } while(!validPosition);
        
        obstacleCount++;
    }
}

void initWall(){
    COORD coord;
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    for(int i=0; i<WIDE; i++){
        coord.X=i;
        coord.Y=0;
        SetConsoleCursorPosition(hOut,coord);
        putchar('#');

        coord.Y=HIGH-1;
        SetConsoleCursorPosition(hOut,coord);
        putchar('#');
    }

    for(int i=1; i<HIGH-1; i++){
        coord.X=0;
        coord.Y=i;
        SetConsoleCursorPosition(hOut,coord);
        putchar('#');

        coord.X=WIDE-1;
        SetConsoleCursorPosition(hOut,coord);
        putchar('#');   
    }
}

//初始界面控件
void initUI(){
    static char screenBuffer[HIGH][WIDE];
    COORD coord;
    HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);

    for(int y=1; y<HIGH-1; y++){
        for(int x=1; x<WIDE-1; x++){
            screenBuffer[y][x]=' ';
        }
    }

    for(size_t i=0; i<snake.size; i++){
        screenBuffer[snake.body[i].Y][snake.body[i].X]=(i==0)?'@':'*';
    }

    screenBuffer[food.Y][food.X]='$';
    
    //在屏幕缓冲区中添加障碍物
    for(int i=0; i<obstacleCount; i++){
        screenBuffer[obstacles[i].Y][obstacles[i].X]='X';
    }

    for(int y=1; y<HIGH-1; y++){
        coord.X=1;
        coord.Y=y;
        SetConsoleCursorPosition(hOut,coord);

        for(int x=1; x<WIDE-1; x++){
            putchar(screenBuffer[y][x]);
        }
    }

    showLevalInfo();
}

void handleInput(){
    if(_kbhit()){
        char key=_getch();

        switch(key){
            case 'W':
            case 'w':if(game.lastDir!=DIR_DOWN) game.currentDir=DIR_UP; break;
            case 'S':
            case 's' :if(game.lastDir!=DIR_UP) game.currentDir=DIR_DOWN; break;
            case 'A':
            case 'a' :if(game.lastDir!=DIR_RIGHT) game.currentDir=DIR_LEFT; break;
            case 'D':
            case 'd':if(game.lastDir!=DIR_LEFT) game.currentDir=DIR_RIGHT; break;
            case 'Q':
            case 'q':game.gameOver=true; break;
            case ' ':isPaused=!isPaused;
                     if(isPaused){
                          showPauseScreen();
                       }else{
                          resumeGameScreen();
                       }
        }
    }
}

void moveSnake(){
    lastX=snake.body[snake.size-1].X;
    lastY=snake.body[snake.size-1].Y;

    game.lastDir=game.currentDir;

    for(size_t i=snake.size-1; i>0; i--){
        snake.body[i].X=snake.body[i-1].X;
        snake.body[i].Y=snake.body[i-1].Y;
    }

    switch(game.currentDir){
        case DIR_UP: snake.body[0].Y--; break;
        case DIR_DOWN: snake.body[0].Y++; break;
        case DIR_LEFT: snake.body[0].X--; break;
        case DIR_RIGHT: snake.body[0].X++; break;
    }
}

void checkCrush(){
    if(isPaused) return;

    if(snake.body[0].X<=0||snake.body[0].X>=WIDE-1||
       snake.body[0].Y<=0||snake.body[0].Y>=HIGH-1){
        game.gameOver=TRUE;
    }

    for(size_t i=1; i<snake.size; i++){
        if(snake.body[0].X==snake.body[i].X&&snake.body[0].Y==snake.body[i].Y){
            game.gameOver=TRUE;
        }
    }
    
    // 检查是否撞到障碍物
    for(int i=0; i<obstacleCount; i++){
        if(snake.body[0].X==obstacles[i].X&&snake.body[0].Y==obstacles[i].Y){
            game.gameOver=TRUE;
        }
    }

    if(snake.body[0].X==food.X&&snake.body[0].Y==food.Y){
        snake.size++;
        game.score += 10;

        updateLevel();
        initFood();
        
        // 每吃5个食物，重新生成障碍物
        if(game.score % (50 * game.level) == 0){
            initObstacles();
        }
    }
}

// 更新关卡函数
void updateLevel() {
    int newLevel = game.score / 30 + 1;
    
    if (newLevel > game.level) {
        game.level = newLevel;
        
        if (game.speed > 50) {
            game.speed -= 10;
        }
        
        COORD coord;
        coord.X = WIDE / 2 - 5;
        coord.Y = HIGH / 2;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
        printf("LEVEL UP! %d", game.level);
        Sleep(1000);
        
        
        initObstacles();
    }
}

void showLevalInfo(){
    COORD coord;

    coord.X=2;
    coord.Y=HIGH;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    printf("SCORE: %d", game.score);

    coord.Y=HIGH+1;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    printf("LEVEL: %d", game.level);
    
    // 显示当前关卡规则
    coord.Y=HIGH+2;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    printf("OBSTACLES: %d", obstacleCount);

    coord.Y=HIGH+3;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    printf("Controls: W/S/A/D to move, Space to pause, Q to quit");
}

void playGame(){
    initGame();
    initSnake();
    initFood();
    initWall();
    
    initObstacles();


    while(!game.gameOver){
        handleInput();
        
        // 暂停时跳过游戏逻辑
        if(isPaused){
            Sleep(300); 
            continue;
        }
        
        moveSnake();
        checkCrush();
        
        if(!game.gameOver){
            initUI();
        }
        
        Sleep(game.speed);
    }
    
}
